import storage from '@/libs/storage';
import { Respone, err401 } from './respone';
import { refreshTokenApi } from '@/services/user';

const localKey = 'dkyj';

let refreshing = false;

const tokenTasks: API.TaskResolve[] = [];

function getTokenJson<V = any>() {
  const res = storage.get(localKey);
  if (res) return JSON.parse(res) as V;
}

const setTokenJson = (json: Partial<API.LoginRes>) => {
  storage.set(localKey, JSON.stringify(json));
}

// 删除 token
export const deleteToken = () => {
  setTokenJson({});
}

// 检查是否已过期
function checkExpires(skip = false, date: number) {
  if (skip) return false;
  const now = Date.now();
  // 时间需要提前2小时
  const leadTime = 2 * 60 * 60 * 1000;
  return (now + leadTime) > date;
}

function completeTasks(token: string) {
  tokenTasks.forEach(task => task(token));
  tokenTasks.length = 0;
}

// 刷新 token
const refreshTokenHandler = async (token: string) => {
  let accessToken = '';
  try {
    const json = await refreshTokenApi(token);
    accessToken = json.accessToken;
    setTokenJson(json);
  } catch (err) {
    if (err instanceof Respone) {
      if (err.code === err401.code) {
        deleteToken();
      }
    }
  } finally {
    refreshing = false;
    completeTasks(accessToken);
  }
};

// 获取 token
const getToken = (skipExpired = false) => {
  return new Promise<string>(async resolve => {
    const data = getTokenJson<API.LoginRes>();
    const rToken = data?.refreshToken;
    const expires = data?.expiresAt || 0;
    const token = data?.accessToken || '';

    if (!rToken) {
      resolve('');
      return;
    }

    // 检查时间是否过期
    if (checkExpires(skipExpired, expires)) {
      tokenTasks.push(resolve);
      if (!refreshing) {
        refreshing = true;
        await refreshTokenHandler(rToken);
      }
    } else {
      resolve(token);
    }
  });
}

// 保存 token 信息
export const saveToken = setTokenJson;

export default getToken;